﻿using System;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace LdCms.Web.Controllers.API.Map.V1
{
    using LdCms.Common.Extension;
    using LdCms.Common.Net;
    using LdCms.EF.DbModels;
    using LdCms.IBLL.Map;
    using LdCms.Plugins.Map.Tencent;
    using LdCms.Plugins.Map.Tencent.Models;
    using LdCms.Web.Services;

    /// <summary>
    /// 腾讯地图 WebService API 注：入口参数为官方参数参数
    ///     1、地点搜索
    ///        URL：map/tencent/ws/place/search?uuid=uuid     
    ///        POST：{"keyword":"美食","boundary":"region(佛山,0)"}
    ///     2、关键字输入提示
    ///        URL：map/tencent/ws/place/suggestion?uuid=uuid    
    ///        POST：{"keyword":"美食","region":"佛山"}
    ///     3、逆地址解析(坐标位置描述)
    ///        URL：map/tencent/ws/geocoder/location?uuid=uuid   
    ///        POST：{"location":"39.984154,116.307490"}
    ///     4、地址解析(地址转坐标)
    ///        URL：map/tencent/ws/geocoder/address?uuid=uuid   
    ///        POST：{"address":"北京市海淀区彩和坊路海淀西大街74号"}
    ///     5、行政区划 - 全部
    ///        URL：map/tencent/ws/district/list?uuid=uuid  
    ///        POST：{"id":""}
    ///     6、行政区划 - 指定行政区划的子级行政区划
    ///        URL：map/tencent/ws/district/getchildren?uuid=uuid  
    ///        POST：{"id":"110000"}
    ///     7、行政区划 - 关键词搜索行政区划
    ///        URL：map/tencent/ws/district/search?uuid=uuid  
    ///        POST：{"keyword":"北京 "}
    ///     8、驾车（driving）路线规划
    ///        URL：map/tencent/ws/direction/driving?uuid=uuid  
    ///        POST：{"from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///     9、步行（walking）路线规划
    ///        URL：map/tencent/ws/direction/walking?uuid=uuid  
    ///        POST：{"from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///    10、骑行（bicycling）路线规划
    ///        URL：map/tencent/ws/direction/bicycling?uuid=uuid  
    ///        POST：{"from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///    11、公交（transit）路线规划
    ///        URL：map/tencent/ws/direction/transit?uuid=uuid  
    ///        POST：{"from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///    12、距离计算（一对多）
    ///        URL：map/tencent/ws/distance?uuid=uuid  
    ///        POST：{"mode":"driving","from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///    13、距离计算（多对多）
    ///        URL：map/tencent/ws/distance/matrix?uuid=uuid  
    ///        POST：{"mode":"driving","from":"40.034852,116.319820","to":"39.771075,116.351395"}
    ///    14、坐标转换
    ///        URL：map/tencent/ws/coord/translate?uuid=uuid  
    ///        POST：{"locations":"39.12,116.83;30.21,115.43","type":"3"}
    ///    15、IP定位
    ///        URL：map/tencent/ws/location/ip?uuid=uuid   
    ///        POST：{"ip":"134.175.144.204"}
    /// </summary>
    [ApiVersion("1.0")]
    [ControllerName("map/tencent/ws")]
    public class MapTencentWebServiceController : BaseApiController
    {
        private readonly IBaseApiManager BaseApiManager;
        private readonly IHttpContextAccessor Accessor;
        private readonly ITencentPlatformService TencentPlatformService;
        public MapTencentWebServiceController(IBaseApiManager BaseApiManager, IHttpContextAccessor Accessor, ITencentPlatformService TencentPlatformService) : base(BaseApiManager)
        {
            this.BaseApiManager = BaseApiManager;
            this.Accessor = Accessor;
            this.TencentPlatformService = TencentPlatformService;
        }

        private Ld_Map_TencentPlatform MapTencentPlatform
        {
            get
            {
                return GetMapTencentPlatform();
            }
        }
        private TencentMapHelper TencentMapHelper
        {
            get
            {
                return GetTencentMapHelper();
            }
        }
        private Ld_Map_TencentPlatform GetMapTencentPlatform()
        {
            try
            {
                string uuid = Uuid;
                if (!IsUuid(uuid))
                    throw new Exception("verify uuid fail！");
                var interfaceAccount = GetSysInterfaceAccountByUuid(uuid);
                return TencentPlatformService.GetTencentPlatformByDefault(interfaceAccount.SystemID, interfaceAccount.CompanyID);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private TencentMapHelper GetTencentMapHelper()
        {
            try
            {
                Ld_Map_TencentPlatform entity = MapTencentPlatform;
                if (entity == null)
                    throw new Exception("get tencent map helper config fail！");
                string key = entity.Key;
                string sk = entity.SK;
                return new TencentMapHelper(key, sk);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        #region 地点搜索
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("place/search")]
        public IActionResult PlaceSearch(string uuid, [FromBody]PlaceSearch formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsPlaceSearchParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetPlaceSearch(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 关建字搜索
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("place/suggestion")]
        public IActionResult PlaceSuggestion(string uuid, [FromBody]PlaceSuggestion formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsPlaceSuggestionParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetPlaceSuggestion(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 逆地址解析(坐标位置描述)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("geocoder/location")]
        public IActionResult GeocoderLocation(string uuid, [FromBody]GeocoderLocation formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsGeocoderLocationParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetGeocoderLocation(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 地址解析(地址转坐标)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("geocoder/address")]
        public IActionResult GeocoderAddress(string uuid, [FromBody]GeocoderAddress formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsGeocoderAddressParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetGeocoderAddress(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 行政区划
        [HttpPost]
        [ActionName("district/list")]
        public IActionResult DistrictList(string uuid, [FromBody]DistrictList formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDistrictListParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDistrictList(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        [HttpPost]
        [ActionName("district/getchildren")]
        public IActionResult DistrictGetchildren(string uuid, [FromBody]DistrictGetchildren formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDistrictGetchildrenParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDistrictGetchildren(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        [HttpPost]
        [ActionName("district/search")]
        public IActionResult DistrictSearch(string uuid, [FromBody]DistrictSearch formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDistrictSearchParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDistrictSearch(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 路线规划服务
        [HttpPost]
        [ActionName("direction/driving")]
        public IActionResult DirectionDriving(string uuid, [FromBody]DirectionDriving formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDirectionDrivingParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDirectionDriving(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        [HttpPost]
        [ActionName("direction/walking")]
        public IActionResult DirectionWalking(string uuid, [FromBody]DirectionWalking formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDirectionWalkingParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDirectionWalking(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        [HttpPost]
        [ActionName("direction/bicycling")]
        public IActionResult DirectionBicycling(string uuid, [FromBody]DirectionBicycling formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDirectionBicyclingParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDirectionBicycling(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        [HttpPost]
        [ActionName("direction/transit")]
        public IActionResult DirectionTransit(string uuid, [FromBody]DirectionTransit formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDirectionTransitParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDirectionTransit(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 距离计算（一对多）
        [HttpPost]
        [ActionName("distance")]
        public IActionResult Distance(string uuid, [FromBody]Distance formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDistanceParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDistance(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 距离计算（多对多）
        [HttpPost]
        [ActionName("distance/matrix")]
        public IActionResult DistanceMatrix(string uuid, [FromBody]DistanceMatrix formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsDistanceMatrixParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetDistanceMatrix(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region IP定位
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("coord/translate")]
        public IActionResult CoordTranslate(string uuid, [FromBody]CoordTranslate formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsCoordTranslateParams(formValue);
                formValue.key = TencentMapHelper.Key;
                var result = TencentMapHelper.GetCoordTranslate(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 坐标转换
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uuid"></param>
        /// <param name="formValue"></param>
        /// <returns></returns>
        [HttpPost]
        [ActionName("location/ip")]
        public IActionResult LocationIp(string uuid, [FromBody]LocationIp formValue)
        {
            long logId = 0;
            try
            {
                logId = BaseApiManager.SaveLogs(uuid, formValue);
                bool sisParams = IsLocationIpParams(formValue);
                formValue.key = TencentMapHelper.Key;
                if (string.IsNullOrEmpty(formValue.ip))
                    formValue.ip = Net.Ip;
                var result = TencentMapHelper.GetLocationIp(formValue);
                return Result(logId, result);
            }
            catch (Exception ex)
            {
                return Error(logId, ex.Message);
            }
        }
        #endregion

        #region 验证传入参数
        private bool IsPlaceSearchParams(PlaceSearch formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.keyword))
                    throw new Exception("lack keyword params！");
                if (string.IsNullOrEmpty(formValue.boundary))
                    throw new Exception("lack boundary params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsPlaceSuggestionParams(PlaceSuggestion formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.keyword))
                    throw new Exception("lack keyword params！");
                if (string.IsNullOrEmpty(formValue.region))
                    throw new Exception("lack region params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsGeocoderLocationParams(GeocoderLocation formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.location))
                    throw new Exception("lack location params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsGeocoderAddressParams(GeocoderAddress formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.address))
                    throw new Exception("lack address params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDistrictListParams(DistrictList formValue)
        {
            try
            {
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDistrictGetchildrenParams(DistrictGetchildren formValue)
        {
            try
            {
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDistrictSearchParams(DistrictSearch formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.keyword))
                    throw new Exception("lack keyword params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDirectionDrivingParams(DirectionDriving formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDirectionWalkingParams(DirectionWalking formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDirectionBicyclingParams(DirectionBicycling formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDirectionTransitParams(DirectionTransit formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDistanceParams(Distance formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.mode))
                    throw new Exception("lack mode params！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsDistanceMatrixParams(DistanceMatrix formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.mode))
                    throw new Exception("lack mode params！");
                if (string.IsNullOrEmpty(formValue.from))
                    throw new Exception("lack from params！");
                if (string.IsNullOrEmpty(formValue.to))
                    throw new Exception("lack from params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsCoordTranslateParams(CoordTranslate formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                if (string.IsNullOrEmpty(formValue.locations))
                    throw new Exception("lack locations params！");
                if (string.IsNullOrEmpty(formValue.type))
                    throw new Exception("lack type params！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        private bool IsLocationIpParams(LocationIp formValue)
        {
            try
            {
                if (formValue == null)
                    throw new Exception("params not empty！");
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion

    }
}